# -*- coding: utf-8 -*-

#   This file is part of emesene.
#
#    Emesene is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    emesene is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with emesene; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

VERSION = '2.4'

import Plugin
from Parser import Url
import gtk
import urllib2
import warnings

ERROR = ''
MIMETYPE = 'application/x-picture-preview'
OBJECT_TEMPLATE = '<object class="%s" type="' + MIMETYPE + '"/>'
SIZELIST = [ '50x50', '100x100', '150x150', '200x200' ]
METHODLIST = [ 'Tooltip', 'InText' ]

class MainClass(Plugin.Plugin):
    description = _('Displays thumbnails of pictures links')
    authors = {'Sébastien Débia': 'sebastien.debia@gmail.com'}
    website = ''
    displayName = _('Picture Preview')
    name = 'PicturePreview'
    def __init__(self, controller, msn):
        Plugin.Plugin.__init__(self, controller, msn)

        self.description = _('Displays thumbnails of pictures links')
        self.authors = {'Sébastien Débia': 'sebastien.debia@gmail.com'}
        self.website = ''
        self.displayName = _('Picture Preview')
        self.name = 'PicturePreview'

        self.controller = controller
        self.parser = controller.unifiedParser
        self.convManager = controller.conversationManager
        
        self.config = controller.config
        self.config.readPluginConfig(self.name)
        self.size = self.config.getPluginValue(self.name, 'size', '')
        if self.size == '':
            self.size = SIZELIST[0]
            
        self.method = self.config.getPluginValue(self.name, 'method', '')
        if self.method == '':
            self.method = METHODLIST[0]
        
        self.postParseId = None

    def start(self):
        self.postParseId = self.parser.connect('filter', self.parseUrl )
        self.convManager.connect( 'new-conversation-ui', \
            self.newConversationWindow )

        for conversation in self.getOpenConversations():
            textView = conversation.ui.textview
            textView.customObjectsCallbacks.update({
                MIMETYPE: (self.miniature,None)
             })
        self.enabled = True
        

    def stop(self):
        self.enabled = False

    def check(self):
        '''
        check if everything is OK to start the plugin
        return a tuple whith a boolean and a message
        if OK -> ( True , 'some message' )
        else -> ( False , 'error message' )
        '''
        if ERROR != '':
            return ( False, ERROR )
            
        return ( True, 'Ok' )
    
    def configure(self):
        '''Configuration Dialog'''
        l=[]
        l.append(Plugin.Option('size', list, _('Thumbnail size:'), '', 
                 self.config.getPluginValue( self.name, 'size', '' ), SIZELIST))
        l.append(Plugin.Option('method', list, _('Display method:'), '', 
                 self.config.getPluginValue( self.name, 'method', '' ), METHODLIST))
        
        response = Plugin.ConfigWindow(_('Picture Preview Configuration'), l).run()
        
        if response != None:
            self.size = response['size'].value
            self.method = response['method'].value
            self.config.setPluginValue(self.name,'size', self.size)
            self.config.setPluginValue(self.name,'method', self.method)
        return True
    
    def parseUrl( self, parser, dataType, filterdata ):
        if not dataType or dataType.getDataType() != 'conversation':
            return

        newObjects = []
        for object in filterdata.list:
            code = ''
            if type(object) == Url and \
               ( object.url.lower().count('.jpg') or \
               object.url.lower().count('.jpeg') or \
               object.url.lower().count('.png') or \
               object.url.lower().count('.gif') ):
                
                code = OBJECT_TEMPLATE % object
                html = object.getHtml()
                object.getHtml = lambda: code + html
            
            newObjects.append(object)
        filterdata.list = newObjects

    def newConversationWindow( self, conversationmanager, conversation, win ):
        textView = conversation.ui.textview
        textView.customObjectsCallbacks.update({
                       MIMETYPE: (self.miniature,None)
                     })
    
        
    def miniature( self, textview, id, test, path=None ):
        img = Preview(textview, id, self)        
        return img
        

'''  This class contains the preview (the icon + the picture) '''
class Preview(gtk.Image):

    def __init__(self, textview, id, plugin):
        
        gtk.Image.__init__(self)
        
        self.plugin = plugin
        
        # the picture of the link
        self.image = gtk.Image()
        self.image.set_from_stock( gtk.STOCK_MISSING_IMAGE, \
                            gtk.ICON_SIZE_SMALL_TOOLBAR )
        
        
        
        if self.plugin.method == "Tooltip":
            self.set_from_stock( gtk.STOCK_ORIENTATION_PORTRAIT, \
                                 gtk.ICON_SIZE_SMALL_TOOLBAR )
            self.set_property('has-tooltip', True)
            self.connect( 'query-tooltip', self.tooltipEvent)
        else:
            self.set_from_stock( gtk.STOCK_MISSING_IMAGE, \
                                 gtk.ICON_SIZE_SMALL_TOOLBAR )
        
        def getImage():
            try:
                #thanks Dainaccio
                req = urllib2.Request(url=id,headers={'User-Agent':'Mozilla/5.0'})
                mem = urllib2.urlopen(req).read(10*1024*1024)

                loader = gtk.gdk.PixbufLoader()
                loader.write(mem)
                loader.close()
                if self.plugin.method == "InText":
                    return (textview, loader, self)
                else:
                    return (textview, loader, self.image)
            except:
                return
        
        defrun = Plugin.Function(getImage, self.callback)
        defrun()
        
        self.show()
        
    
    def tooltipEvent(self, widget, x, y, keyboard_mode, tooltip):
        if self.image.get_storage_type() == gtk.IMAGE_PIXBUF:
            tooltip.set_icon(self.image.get_pixbuf())
        else:
            tooltip.set_icon_from_stock( gtk.STOCK_MISSING_IMAGE, \
                            gtk.ICON_SIZE_SMALL_TOOLBAR )
        return True
    
    
    def callback(self, handler):
        try:
            maxsize = int(self.plugin.size.split('x')[0])
            
            textview, loader, img = handler
            textview.scrollLater()
            pixbuf = loader.get_pixbuf()
            
            width = pixbuf.get_width()
            height = pixbuf.get_height()
	    if width > height:
                    if width < maxsize:
                        ratio = 1
                    else:
                        ratio = float(width)/float(maxsize)
            else:
                    if height < maxsize:
                        ratio = 1
                    else:
                        ratio = float(height)/float(maxsize)
            
            width = int(width/ratio)
            height = int(height/ratio)
            
            scaled_buf = pixbuf.scale_simple(width,height,gtk.gdk.INTERP_BILINEAR)
            img.set_from_pixbuf(scaled_buf)
        except Exception, e:
            pass
